package com.example.apidocserver.interfaces.assembler;

import com.alibaba.druid.util.StringUtils;
import com.example.apidocserver.domain.document.entity.*;
import com.example.apidocserver.infrastructure.util.ParamUtil;
import com.example.apidocserver.infrastructure.util.result.ParamException;

import java.nio.charset.StandardCharsets;
import java.util.*;

import static com.example.apidocserver.infrastructure.constants.SystemConstants.*;

/**
 * 文档对象检测
 *
 * @author xyqlg
 */
public class DocumentAssembler {
    public static void check(ApiDocument document) {
        if (Objects.isNull(document) || StringUtils.isEmpty(document.getDocName()) || document.getDocName().length() > 50) {
            throw new ParamException("文档名称不能为空，且长度不能超过50个字符");
        }
    }

    /**
     * 接口示例标准认证
     *
     * @param apiParamHis 接口示例对象
     */
    public static void paramHisStandard(ApiParamHis apiParamHis) {
        if (Objects.isNull(apiParamHis.getEnvId()) || Objects.isNull(apiParamHis.getApiId())) {
            throw new ParamException("环境和接口id不能为空。");
        }
        if (StringUtils.isEmpty(apiParamHis.getParamName())) {
            throw new ParamException("名称不能为空。");
        }

        // 标准入参
        if (!Objects.isNull(apiParamHis.getParamInputHeaderStr())) {
            apiParamHis.setParamInputHeaderStr(apiParamHis.getParamInputHeaderStr().trim());
        }
        if (!Objects.isNull(apiParamHis.getParamInputPathStr())) {
            String path = apiParamHis.getParamInputPathStr().trim();
            if (path.length() > 0 && path.getBytes(StandardCharsets.UTF_8)[0] != PATH_BASE) {
                path = PATH_BASE_STR + path;
            }
            apiParamHis.setParamInputPathStr(path);
        }
        if (!Objects.isNull(apiParamHis.getParamInputQueryStr())) {
            String query = apiParamHis.getParamInputQueryStr().trim();
            if (query.length() > 0 && query.getBytes(StandardCharsets.UTF_8)[0] != QUERY_START) {
                query = QUERY_START_STR + query;
            }
            apiParamHis.setParamInputQueryStr(query);
        }
        if (!Objects.isNull(apiParamHis.getParamOutputHeaderStr())) {
            apiParamHis.setParamOutputHeaderStr(apiParamHis.getParamOutputHeaderStr().trim());
        }
    }

    /**
     * 校验增加目录参数
     *
     * @param docMenu 目录数据对象
     * @return 接口信息对象
     */
    public static Optional<ApiInfo> checkAddMenu(DocMenu docMenu) {
        if (StringUtils.isEmpty(docMenu.getMenuName()) || Objects.isNull(docMenu.getDocId())) {
            throw new ParamException("文档id或名称不能为空。");
        }

        // 标准数据
        if (Objects.isNull(docMenu.getParentId())) {
            docMenu.setParentId(DATA_COMMON_ID);
        }
        docMenu.setMenuName(docMenu.getMenuName().trim());
        if (!Objects.isNull(docMenu.getDesc())) {
            docMenu.setDesc(docMenu.getDesc().trim());
        }

        // 判断是接口还是ml
        if (MENU_URI_TYPE.equals(docMenu.getMenuType())) {
            if (StringUtils.isEmpty(docMenu.getApiUri()) || StringUtils.isEmpty(docMenu.getApiType())) {
                throw new ParamException("uri或接口类型为空");
            }
            ApiInfo apiInfo = new ApiInfo();
            String path = docMenu.getApiUri().trim();
            apiInfo.setApiUri(ParamUtil.pathParamStandard(path)).setApiType(docMenu.getApiType())
                    .setApiDesc(docMenu.getDesc()).setId(docMenu.getApiId()).setApiName(docMenu.getMenuName());
            if (Objects.isNull(apiInfo.getId())) {
                docMenu.setPrimaryFlag(YES);
            }
            return Optional.of(apiInfo);
        }
        return Optional.empty();
    }


    /**
     * 校验字段数据
     *
     * @param fields 字段说明数据
     * @param apiId  接口id
     */
    private static void checkFields(List<ApiParamField> fields, Integer apiId) {
        Set<String> nameSet = new HashSet<>(fields.size());
        for (ApiParamField field : fields) {
            FieldAssembler.checkField(field);
            if (Objects.isNull(field.getApiId())) {
                field.setApiId(apiId);
            }
            if (nameSet.contains(field.getFieldName())) {
                throw new ParamException("字段名称重复。");
            } else {
                nameSet.add(field.getFieldName());
            }
        }
    }
}
